package com.rookie.data.generate.component.generate;

import com.rookie.data.generate.constant.enums.ColumnRangeEnum;
import com.rookie.data.generate.model.project.FieldProperties;
import com.rookie.data.generate.model.project.TableColumnEntity;
import com.rookie.data.generate.util.GenerateUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;

/**
 * 数字型生成器
 * 如果数据是 decimal，用户定义在数据库定义长度范围内，则以用户定义为准，超出则以数据库定义为准。
 * 如果数据是其他类型，用户定义在数据类型本身范围内则以用户定义为准，超出则以本身长度为准。
 * 初始边界和结束边界，用户定义边界没超过就以用户边界为准，不会全部取代为定义边界。
 *
 * @author rookie
 */
public class NumberGenerate {

    private static final List<String> POINT_TYPE = Arrays.asList("FLOAT", "DOUBLE", "DECIMAL");

    public static Object generate(TableColumnEntity table, FieldProperties properties, ColumnRangeEnum columnRangeEnum) {
        if (properties == null) {
            properties = new FieldProperties();
        }
        String columnType = table.getDataType().toUpperCase();
//        浮点型数据
        if (POINT_TYPE.contains(columnType)) {
            if (columnRangeEnum == ColumnRangeEnum.DECIMAL) {
//                处理 decimal 的范围
                processDecimalRange(table, properties);
            }
            return generateBigDecimal(properties, columnRangeEnum);
        } else {
            return generateInt(properties, columnRangeEnum);
        }
    }

    protected static int generateInt(FieldProperties properties, ColumnRangeEnum columnRangeEnum) {
        int[] range = GenerateUtils.getRange(properties, columnRangeEnum);
        return range[0] + GenerateUtils.RANDOM.nextInt(range[1] - range[0]);
    }

    private static BigDecimal generateBigDecimal(FieldProperties properties, ColumnRangeEnum columnRangeEnum) {
        int point = properties.getPointLength() == null || properties.getPointLength() < 0 ? 2 : properties.getPointLength();
        int[] range = GenerateUtils.getRange(properties, columnRangeEnum);
        return new BigDecimal(range[0]).add(BigDecimal.valueOf((range[1] - range[0]) * GenerateUtils.RANDOM.nextDouble())).setScale(point, RoundingMode.HALF_DOWN);
    }

    private static void processDecimalRange(TableColumnEntity table, FieldProperties properties) {
        String str = "(";
        //                获取 decimal 的范围
        String[] split = table.getColumnType().substring(table.getColumnType().indexOf(str))
                .replace("(", "")
                .replace(")", "")
                .split(",");
        int[] arr = new int[2];
        arr[0] = Integer.parseInt(split[0].trim());
        arr[1] = Integer.parseInt(split[1].trim());
        properties.setPointLength(arr[1]);
//                获取数据的最大长度
        int max = arr[0] - arr[1];
//                计算数据最大值
        int maxValue = Double.valueOf(Math.pow(10, max)).intValue() - 1;
//                如果代码配置的数据值小于数据库定义的最大值则以代码配置为准
        if (properties.getMaxValue() == null || properties.getMaxValue() >= maxValue) {
            //                    如果数据库定义的长度超出了10则设置范围为 Integer 的最大值
            if (max >= 10) {
                properties.setMaxValue(Integer.MAX_VALUE);
            } else {
                properties.setMaxValue(maxValue);
            }
        }

    }
}
